package dao;

import util.DatabaseConnection;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统设置数据访问对象
 */
public class SystemSettingsDAO {

    /**
     * 获取所有系统设置
     */
    public Map<String, String> getAllSettings() throws SQLException {
        String sql = "SELECT setting_key, setting_value FROM system_settings WHERE is_active = TRUE";
        Map<String, String> settings = new HashMap<>();

        try (Connection conn = DatabaseConnection.getConnection();
                PreparedStatement stmt = conn.prepareStatement(sql);
                ResultSet rs = stmt.executeQuery()) {

            while (rs.next()) {
                settings.put(rs.getString("setting_key"), rs.getString("setting_value"));
            }
        }
        return settings;
    }

    /**
     * 根据分类获取设置
     */
    public Map<String, String> getSettingsByCategory(String category) throws SQLException {
        String sql = "SELECT setting_key, setting_value FROM system_settings " +
                "WHERE category = ? AND is_active = TRUE";
        Map<String, String> settings = new HashMap<>();

        try (Connection conn = DatabaseConnection.getConnection();
                PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, category);
            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                settings.put(rs.getString("setting_key"), rs.getString("setting_value"));
            }
        }
        return settings;
    }

    /**
     * 获取单个设置值
     */
    public String getSetting(String key) throws SQLException {
        String sql = "SELECT setting_value FROM system_settings WHERE setting_key = ? AND is_active = TRUE";

        try (Connection conn = DatabaseConnection.getConnection();
                PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, key);
            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                return rs.getString("setting_value");
            }
        }
        return null;
    }

    /**
     * 更新设置值
     */
    public boolean updateSetting(String key, String value, int adminUserId, String reason) throws SQLException {
        String selectSql = "SELECT setting_value FROM system_settings WHERE setting_key = ?";
        String updateSql = "UPDATE system_settings SET setting_value = ?, update_time = CURRENT_TIMESTAMP " +
                "WHERE setting_key = ?";
        String logSql = "INSERT INTO system_settings_log (setting_key, old_value, new_value, change_reason, admin_user_id) "
                +
                "VALUES (?, ?, ?, ?, ?)";

        try (Connection conn = DatabaseConnection.getConnection()) {
            conn.setAutoCommit(false);

            try {
                // 先获取旧值
                String oldValue = null;
                try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
                    selectStmt.setString(1, key);
                    ResultSet rs = selectStmt.executeQuery();
                    if (rs.next()) {
                        oldValue = rs.getString("setting_value");
                    }
                }

                // 更新设置
                try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
                    updateStmt.setString(1, value);
                    updateStmt.setString(2, key);
                    int updated = updateStmt.executeUpdate();

                    if (updated == 0) {
                        conn.rollback();
                        return false;
                    }
                }

                // 记录日志
                try (PreparedStatement logStmt = conn.prepareStatement(logSql)) {
                    logStmt.setString(1, key);
                    logStmt.setString(2, oldValue);
                    logStmt.setString(3, value);
                    logStmt.setString(4, reason);
                    logStmt.setInt(5, adminUserId);
                    logStmt.executeUpdate();
                }

                conn.commit();
                return true;

            } catch (SQLException e) {
                conn.rollback();
                throw e;
            } finally {
                conn.setAutoCommit(true);
            }
        }
    }

    /**
     * 批量更新设置
     */
    public boolean updateMultipleSettings(Map<String, String> settings, int adminUserId, String reason)
            throws SQLException {
        if (settings.isEmpty()) {
            return true;
        }

        try (Connection conn = DatabaseConnection.getConnection()) {
            conn.setAutoCommit(false);

            try {
                // 先获取所有旧值
                Map<String, String> oldValues = new HashMap<>();
                String selectSql = "SELECT setting_key, setting_value FROM system_settings WHERE setting_key = ?";

                for (String key : settings.keySet()) {
                    try (PreparedStatement selectStmt = conn.prepareStatement(selectSql)) {
                        selectStmt.setString(1, key);
                        ResultSet rs = selectStmt.executeQuery();
                        if (rs.next()) {
                            oldValues.put(key, rs.getString("setting_value"));
                        }
                    }
                }

                // 然后批量更新
                for (Map.Entry<String, String> entry : settings.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    String oldValue = oldValues.get(key);

                    // 更新设置
                    String updateSql = "UPDATE system_settings SET setting_value = ?, update_time = CURRENT_TIMESTAMP "
                            +
                            "WHERE setting_key = ?";
                    try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
                        updateStmt.setString(1, value);
                        updateStmt.setString(2, key);
                        updateStmt.executeUpdate();
                    }

                    // 记录日志
                    String logSql = "INSERT INTO system_settings_log (setting_key, old_value, new_value, change_reason, admin_user_id) "
                            +
                            "VALUES (?, ?, ?, ?, ?)";
                    try (PreparedStatement logStmt = conn.prepareStatement(logSql)) {
                        logStmt.setString(1, key);
                        logStmt.setString(2, oldValue);
                        logStmt.setString(3, value);
                        logStmt.setString(4, reason);
                        logStmt.setInt(5, adminUserId);
                        logStmt.executeUpdate();
                    }
                }

                conn.commit();
                return true;

            } catch (SQLException e) {
                conn.rollback();
                throw e;
            } finally {
                conn.setAutoCommit(true);
            }
        }
    }

    /**
     * 获取设置变更日志
     */
    public List<Map<String, Object>> getSettingsLog(int limit) throws SQLException {
        String sql = "SELECT sl.*, u.name as admin_name " +
                "FROM system_settings_log sl " +
                "LEFT JOIN users u ON sl.admin_user_id = u.user_id " +
                "ORDER BY sl.change_time DESC LIMIT ?";

        List<Map<String, Object>> logs = new ArrayList<>();

        try (Connection conn = DatabaseConnection.getConnection();
                PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, limit);
            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                Map<String, Object> log = new HashMap<>();
                log.put("log_id", rs.getInt("log_id"));
                log.put("setting_key", rs.getString("setting_key"));
                log.put("old_value", rs.getString("old_value"));
                log.put("new_value", rs.getString("new_value"));
                log.put("change_reason", rs.getString("change_reason"));
                log.put("admin_name", rs.getString("admin_name"));
                log.put("change_time", rs.getTimestamp("change_time"));
                logs.add(log);
            }
        }
        return logs;
    }

    /**
     * 重置所有设置为默认值
     */
    public boolean resetToDefaults(int adminUserId) throws SQLException {
        Map<String, String> defaultSettings = new HashMap<>();
        defaultSettings.put("MAX_RESERVATION_DAYS", "7");
        defaultSettings.put("MAX_RESERVATION_HOURS", "4");
        defaultSettings.put("ALLOW_CANCEL_RESERVATION", "true");
        defaultSettings.put("CANCEL_DEADLINE_HOURS", "2");
        defaultSettings.put("MORNING_START_TIME", "08:00");
        defaultSettings.put("MORNING_END_TIME", "12:00");
        defaultSettings.put("AFTERNOON_START_TIME", "13:00");
        defaultSettings.put("AFTERNOON_END_TIME", "17:00");
        defaultSettings.put("EVENING_START_TIME", "18:00");
        defaultSettings.put("EVENING_END_TIME", "22:00");
        defaultSettings.put("SYSTEM_NOTICE", "欢迎使用自习室座位预约系统！\n请遵守自习室规章制度，保持安静学习环境。");

        return updateMultipleSettings(defaultSettings, adminUserId, "重置为默认设置");
    }

    /**
     * 获取整型设置值
     */
    public int getIntSetting(String key, int defaultValue) throws SQLException {
        String value = getSetting(key);
        if (value != null) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                // 记录错误但返回默认值
                System.err.println("无效的整型设置值: " + key + " = " + value);
            }
        }
        return defaultValue;
    }

    /**
     * 获取布尔型设置值
     */
    public boolean getBooleanSetting(String key, boolean defaultValue) throws SQLException {
        String value = getSetting(key);
        if (value != null) {
            return "true".equalsIgnoreCase(value) || "1".equals(value);
        }
        return defaultValue;
    }

    /**
     * 初始化默认设置（如果表为空）
     */
    public void initializeDefaultSettings() throws SQLException {
        String countSql = "SELECT COUNT(*) FROM system_settings";

        try (Connection conn = DatabaseConnection.getConnection();
                PreparedStatement stmt = conn.prepareStatement(countSql);
                ResultSet rs = stmt.executeQuery()) {

            if (rs.next() && rs.getInt(1) == 0) {
                // 表为空，插入默认设置
                String insertSql = "INSERT INTO system_settings (setting_key, setting_value, setting_type, description, category) VALUES "
                        +
                        "('MAX_RESERVATION_DAYS', '7', 'INT', '最大提前预约天数', 'RESERVATION'), " +
                        "('MAX_RESERVATION_HOURS', '4', 'INT', '单次最大预约时长（小时）', 'RESERVATION'), " +
                        "('ALLOW_CANCEL_RESERVATION', 'true', 'BOOLEAN', '是否允许用户取消预约', 'RESERVATION'), " +
                        "('CANCEL_DEADLINE_HOURS', '2', 'INT', '取消预约截止时间（小时前）', 'RESERVATION'), " +
                        "('MORNING_START_TIME', '08:00', 'TIME', '上午时段开始时间', 'TIMESLOT'), " +
                        "('MORNING_END_TIME', '12:00', 'TIME', '上午时段结束时间', 'TIMESLOT'), " +
                        "('AFTERNOON_START_TIME', '13:00', 'TIME', '下午时段开始时间', 'TIMESLOT'), " +
                        "('AFTERNOON_END_TIME', '17:00', 'TIME', '下午时段结束时间', 'TIMESLOT'), " +
                        "('EVENING_START_TIME', '18:00', 'TIME', '晚上时段开始时间', 'TIMESLOT'), " +
                        "('EVENING_END_TIME', '22:00', 'TIME', '晚上时段结束时间', 'TIMESLOT'), " +
                        "('SYSTEM_NOTICE', '欢迎使用自习室座位预约系统！\\n请遵守自习室规章制度，保持安静学习环境。', 'STRING', '系统公告内容', 'NOTICE')";

                try (PreparedStatement insertStmt = conn.prepareStatement(insertSql)) {
                    insertStmt.executeUpdate();
                }
            }
        }
    }
}
